home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 19 code / SimpliFace_V2 / Sources / Application.cp < prev    next >
Encoding:
Text File  |  1994-04-15  |  12.8 KB  |  540 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Application.cp
  3.  
  4.     Contains:    TApplication implementation.
  5.  
  6.     This module derived from the Apple Shared Library Manager
  7.     sample source code supplied with ASLM 1.1 (note that ASLM
  8.     is NOT required for, or used in, this project).
  9.     
  10.  
  11.     Developed by:
  12.  
  13.     Paul G Smith (commstalk hq & Full Moon Software, Inc)
  14.  
  15.     you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  16.     BUT I prefer to be contacted by e-mail
  17.     AppleLink:     COMMSTALK.HQ
  18.     Internet:     COMMSTALK.HQ@applelink.apple.com
  19.  
  20.     "SimpliFace2" Sample code to accompany develop article
  21.     on techniques for controlling script inheritance.
  22.     
  23.     
  24.  
  25.  
  26. */
  27.  
  28. #ifndef __TYPES__
  29. #include <Types.h>
  30. #endif
  31.  
  32. #if MACOS
  33. #ifndef __QUICKDRAW__
  34. #include <QuickDraw.h>
  35. #endif
  36. #endif
  37.  
  38. #ifndef __FONTS__
  39. #include <Fonts.h>
  40. #endif
  41. #ifndef __EVENTS__
  42. #include <Events.h>
  43. #endif
  44. #ifndef __WINDOWS__
  45. #include <Windows.h>
  46. #endif
  47. #ifndef __MENUS__
  48. #include <Menus.h>
  49. #endif
  50. #ifndef __DIALOGS__
  51. #include <Dialogs.h>
  52. #endif
  53. #ifndef __TOOLUTILS__
  54. #include <ToolUtils.h>
  55. #endif
  56. #ifndef __MEMORY__
  57. #include <Memory.h>
  58. #endif
  59. #ifndef __SEGLOAD__
  60. #include <SegLoad.h>
  61. #endif
  62. #ifndef __OSUTILS__
  63. #include <OSUtils.h>
  64. #endif
  65. #ifndef __TRAPS__
  66. #include <Traps.h>
  67. #endif
  68.  
  69. #ifndef __APPLICATION__
  70. #include <Application.h>
  71. #endif
  72. #ifndef __APPLICATIONCOMMON__
  73. #include "ApplicationCommon.h"
  74. #endif
  75.  
  76. #include "TrapAvailable.cp"
  77.  
  78. // OSEvent is the event number of the suspend/resume and mouse-moved events sent
  79. // by MultiFinder. Once we determine that an event is an osEvent, we look at the
  80. // high byte of the message sent to determine which kind it is. To differentiate
  81. // suspend and resume events we check the resumeMask bit.
  82. const short kOsEvent = app4Evt;                // event used by MultiFinder
  83. const short kSuspendResumeMessage = 0x01;    // high byte of suspend/resume event message
  84. const short kClipConvertMask = 0x02;        // bit of message Label clip conversion
  85. const short kResumeMask = 0x01;                // bit of message Label for resume vs. suspend
  86. const short kMouseMovedMessage = 0xFA;        // high byte of mouse-moved event message
  87.  
  88. /*******************************************************************************
  89. ** PUBLIC Constructor/Destructor
  90. ********************************************************************************/
  91.  
  92. TApplication::TApplication()
  93.         : TScriptableObject(kOSANullScript)
  94. {
  95.     fDone = NULL;
  96.     fInBackground = false;
  97.     fMouseRgn = NULL;
  98.     fWhichWindow = NULL;
  99.     fqd = NULL;
  100. }
  101.  
  102. TApplication::TApplication(Ptr qdPtr)
  103. {
  104.     InitApplication(qdPtr);
  105. }
  106.  
  107. TApplication::~TApplication(void)
  108. {
  109. }
  110.  
  111. /*******************************************************************************
  112. ** PRIVATE InitApplication
  113. ********************************************************************************/
  114.  
  115. void TApplication::InitApplication(Ptr qdPtr)
  116. {
  117.     SysEnvRec envRec;
  118.     long stkNeeded, heapSize;
  119.     fqd = (qdRec*)qdPtr;
  120.  
  121.     // initialize Mac Toolbox components
  122.     InitGraf(&fqd->thePort);
  123.     InitFonts();
  124.     InitWindows();
  125.     InitMenus();
  126.     TEInit();
  127.     InitDialogs(NULL);
  128.     InitCursor();
  129.  
  130.     // ignore the error returned from SysEnvirons; even if an error occurred,
  131.     // the SysEnvirons glue will fill in the SysEnvRec
  132.     (void) SysEnvirons(curSysEnvVers, &envRec);
  133.  
  134.     // Are we running on a 128K ROM machine or better???
  135.     if (envRec.machineType < 0) {
  136.         TApplication::BigBadError(kApplicationErrStrings,eWrongMachine); // if not, alert & quit
  137.     }
  138.  
  139.     // if we need more stack space, get it now
  140.     stkNeeded = StackNeeded();
  141.     if (stkNeeded > StackSpace())
  142.       {
  143.         // new address is heap size + current stack - needed stack
  144.         SetApplLimit((Ptr) ((long) GetApplLimit() - stkNeeded + StackSpace()));
  145.       }
  146.  
  147.     // Check for minimum heap size
  148.     heapSize = (long) GetApplLimit() - (long) ApplicZone();
  149.     if (heapSize < HeapNeeded()) {
  150.         TApplication::BigBadError(kApplicationErrStrings,eSmallSize);
  151.     }
  152.  
  153.     // expand the heap so new code segments load at the top
  154.     MaxApplZone();
  155.  
  156.     // allocate an empty document list
  157.     // fDocList = new TDocumentList;
  158.  
  159.     // initialize our class variables
  160.     fDone = false;
  161.     fInBackground = false;
  162.     fMouseRgn = NULL;
  163.     fWhichWindow = NULL;
  164. }
  165.  
  166. /**********************************************************************
  167. ** PUBLIC EventLoop
  168. ***********************************************************************/
  169.  
  170.  
  171. Boolean TApplication::HandleEvent(EventRecord& /*theEvent*/, Boolean& /*pass*/)
  172. {
  173.     return false;
  174. }
  175.  
  176. void TApplication::InEventLoop(void)
  177. {
  178.     Boolean gotEvent;
  179.     EventRecord tEvt;
  180.     Boolean pass = false;
  181.     WindowPtr oldWindow;
  182.     
  183.     GetPort(&oldWindow);
  184.  
  185.     // always set up fWhichWindow before doing anything
  186.     fWhichWindow = FrontWindow();
  187.     // make sure we always draw into correct window
  188.     if (fWhichWindow)
  189.         SetPort(fWhichWindow);
  190.  
  191.     DoIdle();            // call idle time handler
  192.     
  193.     gotEvent = WaitNextEvent(everyEvent, &tEvt, SleepVal(), fMouseRgn);
  194.     fTheEvent = tEvt;
  195.  
  196.     // make sure we got a real event
  197.     if ( gotEvent && !HandleEvent(tEvt, pass))
  198.       {
  199.         AdjustCursor();
  200.         switch (tEvt.what)
  201.           {
  202.             case mouseDown :
  203.                 DoMouseDown();
  204.                 break;
  205.             case mouseUp :
  206.                 DoMouseUp();
  207.                 break;
  208.             case keyDown :
  209.             case autoKey :
  210.                 DoKeyDown();
  211.                 break;
  212.             case updateEvt :
  213.                 DoUpdateEvt();                
  214.                 break;
  215.             case diskEvt :
  216.                 DoDiskEvt();
  217.                 break;
  218.             case activateEvt :
  219.                 DoActivateEvt();
  220.                 break;
  221.             case kOsEvent :
  222.                 DoOSEvent();
  223.                 break;
  224.             case kHighLevelEvent:
  225.                 DoHighLevelEvent();
  226.                 break;
  227.             default :
  228.                 break;
  229.           } // end switch (fTheEvent.what)
  230.       }
  231.     AdjustCursor();
  232.  
  233.     SetPort(oldWindow);
  234. }
  235.  
  236. void TApplication::EventLoop(void)
  237. {
  238.     SetUp();                    // call setup routine
  239.     DoIdle();                    // do idle once
  240.  
  241.     while (fDone == false)
  242.     {
  243.         InEventLoop();
  244.     }
  245.     // call cleanup handler
  246.     CleanUp();
  247. }
  248.  
  249. /**********************************************************************
  250. ** PUBLIC StackNeeded/HeapNeeded
  251. ***********************************************************************/
  252.  
  253. long TApplication::StackNeeded()
  254. {
  255.     return 0;
  256. }
  257.  
  258. long TApplication::HeapNeeded()
  259. {
  260.     return 0;
  261. }
  262.  
  263. /**********************************************************************
  264. ** PUBLIC SetUp/Cleanup
  265. ***********************************************************************/
  266.  
  267. void TApplication::SetUp()
  268. {
  269.     // Run before event loop starts
  270. }
  271.  
  272. void TApplication::CleanUp()
  273. {
  274.     // run at end of loop
  275. }
  276.  
  277. /**********************************************************************
  278. ** PUBLIC ExitLoop
  279. ***********************************************************************/
  280.  
  281. void TApplication::ExitLoop(void)
  282. {
  283.     this->fDone = true;
  284. }
  285.  
  286. /**********************************************************************
  287. ** PUBLIC DoIdle
  288. ***********************************************************************/
  289.  
  290. void TApplication::DoIdle()
  291. {
  292.     // idle time handler (blink caret, background tasks)
  293. }
  294.  
  295. /**********************************************************************
  296. ** PUBLIC AdjustMenus
  297. ***********************************************************************/
  298.  
  299. void TApplication::AdjustMenus()
  300. {
  301.     // menu updater routine
  302. }
  303.  
  304. /**********************************************************************
  305. ** PUBLIC DoKeyDown
  306. ***********************************************************************/
  307.  
  308. void TApplication::DoKeyDown(void)
  309. {
  310.     char key;
  311.     long mResult;
  312.  
  313.     key = (char) (fTheEvent.message & charCodeMask);
  314.     if ((fTheEvent.modifiers & cmdKey) && (fTheEvent.what == keyDown))
  315.     {
  316.         // only do command keys if we are not autokeying
  317.         AdjustMenus();                    // make sure menus are up to date
  318.         mResult = MenuKey(key);
  319.         if (mResult != 0)                // if it wasn't a menu key, pass it through
  320.         {
  321.             DoMenuCommand(HiWord(mResult), LoWord(mResult));
  322.             return;
  323.         }
  324.     }
  325. }
  326.  
  327. /**********************************************************************
  328. ** PUBLIC DoHighLevelEvent
  329. ***********************************************************************/
  330. void TApplication::DoHighLevelEvent(void)
  331. {
  332.     EventRecord tEvt = fTheEvent;
  333.     // we copy event record so that we don't pass reference to object Label 
  334.  
  335.     AEProcessAppleEvent(&tEvt);
  336. }
  337.  
  338.  
  339.  
  340. /**********************************************************************
  341. ** PUBLIC DoActivateEvt/DoUpdateEvt
  342. ***********************************************************************/
  343.  
  344. void TApplication::DoActivateEvt(void)
  345. {
  346.     // event record contains window ptr
  347.     fWhichWindow = (WindowPtr) fTheEvent.message;
  348.     SetPort(fWhichWindow);
  349.     
  350. }
  351.  
  352. void TApplication::DoUpdateEvt(void)
  353. {
  354.     // event record contains window ptr
  355.     fWhichWindow = (WindowPtr) fTheEvent.message;
  356.  
  357.     SetPort(fWhichWindow);
  358. }
  359.  
  360. /**********************************************************************
  361. ** PUBLIC DoOSEvent
  362. ***********************************************************************/
  363.  
  364. void TApplication::DoOSEvent(void)
  365. {
  366.     Boolean doConvert;
  367.     unsigned char evType;
  368.  
  369.     // is it a multifinder event?
  370.     evType = (unsigned char) (fTheEvent.message >> 24) & 0x00ff;
  371.     switch (evType) {     // high byte of message is type of event
  372.         case kMouseMovedMessage :
  373.             DoIdle();                    // mouse-moved is also an idle event
  374.             break;
  375.         case kSuspendResumeMessage :
  376.             doConvert = (fTheEvent.message & kClipConvertMask) != 0;
  377.             fInBackground = (fTheEvent.message & kResumeMask) == 0;
  378.             if (fInBackground)
  379.               DoSuspend(doConvert);
  380.             else DoResume(doConvert);
  381.             break;
  382.     }
  383. }
  384.  
  385. /**********************************************************************
  386. ** PUBLIC DoMouseDown
  387. ***********************************************************************/
  388.  
  389. void TApplication::DoMouseDown(void)
  390. {
  391.     long mResult;
  392.     short partCode;
  393.     WindowPtr tWind;
  394.     EventRecord tEvt;
  395.  
  396.     // gotta watch those object Label dereferences
  397.     partCode = FindWindow(fTheEvent.where, &tWind);
  398.     fWhichWindow = tWind;
  399.     tEvt = fTheEvent;
  400.     switch (partCode)
  401.       {
  402.         case inSysWindow :
  403.             DoMouseInSysWindow();
  404.             break;
  405.         case inMenuBar :
  406.             AdjustMenus();
  407.             mResult = MenuSelect(tEvt.where);
  408.             if (mResult != 0)
  409.               DoMenuCommand(HiWord(mResult),LoWord(mResult));
  410.             break;
  411.         case inGoAway :
  412.             DoGoAway();                    
  413.             break;
  414.         case inDrag :
  415.             DoDrag();
  416.             break;
  417.         case inGrow :
  418.             break;
  419.         case inZoomIn :
  420.         case inZoomOut :
  421.             break;
  422.         case inContent :
  423.             // If window is not in front, make it so
  424.             if ( fWhichWindow != FrontWindow() )
  425.               SelectWindow(fWhichWindow);
  426.             break;
  427.       }
  428. }
  429.  
  430. /**********************************************************************
  431. ** PUBLIC DoMouseInSysWindow
  432. ***********************************************************************/
  433.  
  434. void TApplication::DoMouseInSysWindow()
  435. {
  436.     SystemClick(&fTheEvent, fWhichWindow);
  437. }
  438.  
  439. /**********************************************************************
  440. ** PUBLIC DoDrag
  441. ***********************************************************************/
  442.  
  443. void TApplication::DoDrag(void)
  444. {
  445.     DragWindow(fWhichWindow, fTheEvent.where, &fqd->screenBits.bounds);
  446. }
  447.  
  448. /**********************************************************************
  449. ** PUBLIC DoGoAway
  450. ***********************************************************************/
  451.  
  452. void TApplication::DoGoAway(void)
  453. {
  454.     if (TrackGoAway(fWhichWindow, fTheEvent.where)) {
  455.         CloseDeskAcc(((WindowPeek) fWhichWindow)->windowKind);
  456.  
  457.         fWhichWindow = FrontWindow();
  458.         if (fWhichWindow != NULL) {
  459.             SetPort(fWhichWindow);
  460.         }
  461.     }
  462. }
  463.  
  464. /**********************************************************************
  465. ** PUBLIC AdjustCursor
  466. ***********************************************************************/
  467.  
  468. void TApplication::AdjustCursor()
  469. {
  470.     // cursor adjust routine, should setup mouseRgn
  471. }
  472.  
  473. /**********************************************************************
  474. ** PUBLIC DoMenuCommand
  475. ***********************************************************************/
  476.  
  477. void TApplication::DoMenuCommand(short, short)
  478. {
  479. }
  480.  
  481. /**********************************************************************
  482. ** PUBLIC DoSuspend/DoResume
  483. ***********************************************************************/
  484.  
  485. void TApplication::DoSuspend(Boolean /*doClipConvert*/)
  486. {
  487. }
  488.  
  489. void TApplication::DoResume(Boolean /*doClipConvert*/)
  490. {
  491. }
  492.  
  493. /**********************************************************************
  494. ** PUBLIC DoMenuCommand
  495. ***********************************************************************/
  496.  
  497. void TApplication::DoMouseUp()
  498. {
  499. }
  500.  
  501. /**********************************************************************
  502. ** PUBLIC DoDiskEvt
  503. ***********************************************************************/
  504.  
  505. void TApplication::DoDiskEvt()
  506. {
  507. }
  508.  
  509. /**********************************************************************
  510. ** PUBLIC SleepVal
  511. ***********************************************************************/
  512.  
  513. unsigned long TApplication::SleepVal()
  514. {
  515.     return 20;        // how long to sleep in WaitNextEvent
  516. }
  517.  
  518. /**********************************************************************
  519. **  TApplication static methods
  520. ***********************************************************************/
  521.  
  522. void TApplication::AlertUser(short errResID, short errCode)
  523. {
  524.     Str255 message;
  525.  
  526.     GetIndString(message, errResID, errCode);
  527.     #if qDebug
  528.     if (message[0] == 0)
  529.         DebugStr((ConstStr255Param)"\pTApplication::AlertUser could not get error string.");
  530.     #endif
  531.     ParamText(message, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
  532.     (void) Alert(rUserAlert, NULL);
  533. }
  534.  
  535. void TApplication::BigBadError(short errResID, short errCode)
  536. {
  537.     TApplication::AlertUser(errResID,errCode);
  538.     ExitToShell();
  539. }
  540.